package com.student.demo.config;

import cn.hutool.core.date.DateUtil;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.deser.std.DateDeserializers;
import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.jackson.JsonComponent;

import java.io.IOException;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;

/**
 * 日期反序列化
 *
 * @author luqili 2016年7月21日
 */
@JsonComponent
public class JsonDeserializerByDate extends DateDeserializers.DateDeserializer {
    private String formatString;
    private TimeZone tz;
    private Locale loc;

    public JsonDeserializerByDate() {
    }

    public JsonDeserializerByDate(String formatString, TimeZone tz, Locale loc) {
        this.formatString = formatString;
        this.tz = tz;
        this.loc = loc;
    }

    @Override
    public Date deserialize(JsonParser jp, DeserializationContext dc) throws IOException {
        String source = jp.getValueAsString();
        if (StringUtils.isBlank(source)) {
            return null;
        }
        try {
            //支持时间戳处理
            if (StringUtils.isNumeric(source)) {
                return new Date(jp.getValueAsLong());
            }
            Calendar calendar = null;
            if (loc == null) {
                loc = Locale.CHINA;
            }
            if (tz == null) {
                tz = TimeZone.getTimeZone("Asia/Shanghai");
            }
            if (StringUtils.isNotBlank(formatString)) {
                calendar = DateUtil.parseByPatterns(source, loc, formatString, "yyyyMMdd", "yyyyMMddHHmm", "yyyyMMddHHmmss", "yyyy-MM-dd", "yyyy-MM-dd HH:mm", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm:ss:SSS");
            } else {
                calendar = DateUtil.parseByPatterns(source, loc, "yyyyMMdd", "yyyyMMddHHmm", "yyyyMMddHHmmss", "yyyy-MM-dd", "yyyy-MM-dd HH:mm", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm:ss:SSS");
            }
            calendar.setTimeZone(tz);
            return calendar.getTime();
        } catch (Exception e) {
            System.out.println("日期格式化失败");
        }
        return null;
    }

    @Override
    public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanProperty property) throws JsonMappingException {
        final JsonFormat.Value format = findFormatOverrides(ctxt, property, handledType());
        if (format != null) {
            this.formatString = format.hasPattern() ? format.getPattern() : null;
            this.tz = format.hasTimeZone() ? format.getTimeZone() : TimeZone.getTimeZone("Asia/Shanghai");
            this.loc = format.hasLocale() ? format.getLocale() : Locale.CHINA;
            return new JsonDeserializerByDate(formatString, tz, loc);
        }
        return this;
    }
}
